var myGraph;

if (typeof console == undefined) {
  console = {log: function() {}};
}

var applyFormatting = function() {
  if (typeof myGraph == "undefined") {
      return;
  }
  if ($('#kmbformat')[0].checked) {
    myGraph.updateOptions({
      labelsKMB: false,
      axes: {
        y: {
            valueFormatter: function(n, opts, g) {
                return valFormatter(n);
            },
            axisLabelFormatter: function(n, opts, g) {
                return valFormatter(n);
            }
        }
      }
    });
  } else {
    myGraph.updateOptions({
      labelsKMB: true,
      axes: {
        y: {
            valueFormatter: null,
            axisLabelFormatter: null
        }
      }
    });
  }
}

var getCurrDT = function() {
  var d = new Date();
  var tzoffset = d.getTimezoneOffset();
  var offsethr = (tzoffset / 60).toFixed(0);
  var offsetmin = (tzoffset % 60).toFixed(0);
  prefix = ""; suffix = "";
  if (offsethr < 10 && offsethr > -10) { prefix = "0"; }
  if (offsethr > 0) { prefix = "-" + prefix; }
  if (offsetmin < 10) { suffix = "0"; }
  tzspec = prefix + offsethr + ":" + offsetmin + suffix;
  var month = d.getMonth() + 1;
  if (month < 10) { month = "0" + month; }
  var dayofmonth = d.getDate();
  if (dayofmonth < 10) { dayofmonth = "0" + dayofmonth; }
  var hours = d.getHours();
  if (hours < 10) { hours = "0" + hours; }
  var minutes = d.getMinutes();
  if (minutes < 10) { minutes = "0" + minutes; }
  return month + "-" + dayofmonth + "-" + d.getFullYear()
                  + "." + hours + ":" + minutes + tzspec;
};

// transforms a tsdb nanosecond timestamp to a javascript date object
var nanoSecondToDate = function(ns) {
    var d = new Date();
    d.setTime(ns / 1000000);
    d.setMilliseconds(ns % 1000);
    return d;
};

// transforms a tsdb dataset into something dygraph can use.
var arrayToDygraphFormat = function(data) {
    for (var entry in data) {
        data[entry][0] = nanoSecondToDate(data[entry][0]);
    }
    return data;
};

var units = [
    ["GB", 1073741824],
    ["MB", 1048576],
    ["KB", 1024]
];

var valFormatter = function(n, precision) {
    if (typeof precision == "undefined") {
        precision = 2;
    }
    for (i in units) {
        var unitName = units[i][0]; var unit = units[i][1];
        if (n > unit) {
            var val = n / unit;
            return val.toFixed(precision) + unitName;
        }
    }
    return n;
}

var makeGraph = function(id, data) {
    var options = data[1];
    options['legend'] = 'always';
    options['labelsKMB'] = true;
    options['width'] = 600;
    options['height'] = 300;
    options['labelsDiv'] = 'legend';
    options['connectSeparatedPoints'] = true;
    return new Dygraph(document.getElementById(id), data[0], options);
}

var makeFeedUrl = function(dataSpec, startTime, duration) {
    var sources = [];
    for (var i in dataSpec) {
        //console.log("i: ", i);
        //console.log("spec: ", dataSpec[i]);
        sources = sources.concat(
            [
                [dataSpec[i]['source'], dataSpec[i]['varname'].join(',')].join(';')
            ]);
    }
    return ["feed", sources.join('+'), startTime, duration].join("/");
}

// fetch and transform a tsdb timeseries into dygraph format
// then return it
var fetchTimeseries = function(id, dataSpec, startTime, duration) {
    var data;
    $.ajax(makeFeedUrl(dataSpec, startTime, duration), {
      // handle errors
      dataType: "json",
      error: function(xhr, status, err) {
           //console.log("error: ", err);
          $('#g')[0].innerHTML = err;
      },
      success: function(data, status, xhr) {
           var labels = {labels: data['Labels']};
          console.log("labels: ", labels);
           var err = data['Err'];
           var series = data['Data'];
           //console.log("data: ", data);
           if (err == "") {
               console.log("series:", series);
               if (series.length > 0) {
                   if (typeof myGraph == "undefined") {
                       myGraph = makeGraph(id,[arrayToDygraphFormat(series), labels]);
                   } else {
                       console.log("updating current graph");
                       myGraph.updateOptions({file:arrayToDygraphFormat(series),
                                              labels: data['Labels']});
                   }
                   applyFormatting();
                   applyRollPeriod();
               } else {
                   $('#g')[0].innerHTML = "No data for that query...";
               }
           } else {
               $('#g')[0].innerHTML = err;
           }
      }});
}

var parseInput = function() {
    var dataSpec = $('#graphinput')[0].value;
    var specs = dataSpec.split(" ");
    var source;
    var varName;
    var specList = [];
    for (i in specs) {
        var parts = specs[i].split(';');
        source = parts[0];
        varName = parts[1];
        specList = specList.concat([{source: source, varname: [varName]}]);
    }
    return specList;
}

var renderSeries = function() {
    var dateTime = $('#timespec')[0].value;
    var duration = $('#duration')[0].value;
    fetchTimeseries('g', parseInput(), dateTime, duration);
}

var fillFormFromUrl = function() {
    var frag = document.location.hash.substr(1);
    var parts = frag.split("/");
    var ok = false;
    if (parts.length > 0) {
        var sources = parts[0];
        $('#graphinput')[0].value = sources.split("+").join(" ");
        ok = true;
    }
    if (parts.length > 1) {
        var endTime = parts[1];
        if (endTime != "now") {
            $('#timespec')[0].value= "now";
        } else {
            $('#timespec')[0].value= getCurrDT();
        }
    }
    if (parts.length > 2) {
        var duration = parts[2];
        $('#duration')[0].value= duration;
    }
    renderSeries();
}

var makeRollPeriodWatcher = function() {
    var el = $('#rollPeriod')[0];
    var oldVal = el.value;
    return function() {
        if (el.value != oldVal) {
            if (typeof myGraph == "undefined") {
                return;
            }
            if ($('#rolling')[0].checked) {
                myGraph.updateOptions({rollPeriod: el.value});
            } else {
                myGraph.updateOptions({rollPeriod: 1});
            }
            oldVal = el.value;
        }
    };
};

var applyRollPeriod = makeRollPeriodWatcher();

$(document).ready(function() {
    $('#timespec')[0].value = getCurrDT();
    $('#duration')[0].value = "1h";
    $('#render').click(renderSeries);
    $('#rollPeriod')[0].value = "1";
    $('#rolling').change(function() {
      applyRollPeriod();
    });
    $('#rollPeriod').keyup(function() {
      applyRollPeriod();
    });
    $('#kmbformat')[0].checked = true;
    $('#kmbformat').change(function() {
      applyFormatting();
    });
    fillFormFromUrl();
  });

// UI code
